home *** CD-ROM | disk | FTP | other *** search
/ Aminet 5 / Aminet 5 - March 1995.iso / Aminet / mus / edit / AlgoRhythms.lha / AlgoRhythms / Source / forms.c < prev    next >
C/C++ Source or Header  |  1994-11-25  |  29KB  |  842 lines

  1. /* forms.c
  2.     Copyright (c) 1993 by Thomas E. Janzen
  3.     All Rights Reserved
  4.  
  5.     THIS SOFTWARE IS FURNISHED FREE OF CHARGE FOR STUDY AND USE AND MAY
  6.     BE COPIED ONLY FOR PERSONAL USE OR COMPLETELY AS OFFERED WITH NO
  7.     CHANGES FOR FREE DISTRIBUTION.  NO TITLE TO AND OWNERSHIP OF THE
  8.     SOFTWARE IS HEREBY TRANSFERRED.  THOMAS E. JANZEN ASSUMES NO 
  9.     RESPONSIBILITY FOR THE USE OR RELIABILITY OF THIS SOFTWARE.
  10.     
  11.     Thomas E. Janzen
  12.     208A Olde Derby Road
  13.     Norwood, MA  02062-1761
  14.     (617)769-7733
  15.  
  16. **  FACILITY:
  17. **
  18. **    AlgoRhythms music improviser on Commodore (TM) Amiga (TM)
  19. **    compiled with SAS/C Amiga Compiler 6.50 
  20. **
  21. **  ABSTRACT:
  22. **
  23. **    forms.c supports gadgets (using GadTools) for controlling
  24. **    the form of a piece in AlgoRhythms.
  25. **
  26. **  AUTHORS: Thomas E. Janzen
  27. **
  28. **  CREATION DATE:    23-OCT-1993
  29. **
  30. **  MODIFICATION HISTORY:
  31. **    DATE    NAME    DESCRIPTION
  32. **   30 DEC 93 T Janzen new for V3.0
  33. **-- 
  34. */
  35.  
  36. #define INTUI_V36_NAMES_ONLY
  37.  
  38. #include <math.h>
  39. #include <stdlib.h>
  40. #include <stdio.h>
  41.  
  42. #include <exec/types.h>
  43. #include <exec/nodes.h>
  44. #include <intuition/intuition.h>
  45. #include <libraries/gadtools.h>
  46. #include <devices/timer.h>
  47.  
  48. #include <clib/exec_protos.h>
  49. #include <clib/graphics_protos.h>
  50. #include <clib/intuition_protos.h>
  51. #include <clib/gadtools_protos.h>
  52. #include <clib/utility_protos.h>
  53. #include <clib/dos_protos.h>
  54. #include <proto/graphics.h> 
  55. #include <proto/intuition.h>
  56. #include <proto/gadtools.h>
  57.  
  58. #include "scale_list.h"
  59. #include "window.h"
  60. #include "forms.h"
  61. #include "algorhythms.h"
  62. #include "scales.h"
  63.  
  64. #define GAD_PITCH_MEAN_PER (1)
  65. #define GAD_PITCH_MEAN_PHA (2)
  66. #define GAD_PITCH_RANG_PER (3)
  67. #define GAD_PITCH_RANG_PHA (4)
  68. #define GAD_PITCH_RANDOMIZE (5)
  69. #define GAD_PACE_MEAN_PER (6)
  70. #define GAD_PACE_MEAN_PHA (7)
  71. #define GAD_PACE_RANG_PER (8)
  72. #define GAD_PACE_RANG_PHA (9)
  73. #define GAD_PACE_RANDOMIZE (10)
  74. #define GAD_DYN_MEAN_PER (11)
  75. #define GAD_DYN_MEAN_PHA (12)
  76. #define GAD_DYN_RANG_PER (13)
  77. #define GAD_DYN_RANG_PHA (14)
  78. #define GAD_DYN_RANDOMIZE (15)
  79. #define GAD_TEXTURE_RANG_PER (16)
  80. #define GAD_TEXTURE_RANG_PHA (17)
  81. #define GAD_TEXTURE_RANDOMIZE (18)
  82. #define GAD_DURATION (19)
  83. #define GAD_PULSE (20)
  84. #define GAD_MAXVOICES (21)
  85. #define GAD_NOTE_LEN_MIN (22)
  86. #define GAD_NOTE_LEN_MAX (23)
  87. #define GAD_SCALES (24)
  88. #define GAD_TRANSPOSE (25)
  89. #define GAD_LAST (26)
  90.  
  91. #define C_PITCH_X (50)
  92. #define C_PACE_X  (185)
  93. #define C_DYN_X   (320)
  94. #define C_TEXTURE_X (455)
  95. #define C_DUR_X (30)
  96. #define C_MAXVOICES_X (150)
  97. #define C_SCALES_X (440)
  98. #define C_TRANSPOSE_X (112)
  99. #define C_PULSE_X (30)
  100. #define C_MIN_X (250)
  101. #define C_MAX_X (250)
  102.  
  103. #define C_TOP_LINE (25)
  104. #define C_2ND_LINE (52)
  105. #define C_MEAN_PERIOD_Y (80)
  106. #define C_MEAN_PHASE_Y  (92)
  107. #define C_RANG_PERIOD_Y (104)
  108. #define C_RANG_PHASE_Y  (116)
  109. #define C_RAND_Y        (128)
  110.  
  111. #define C_PHASE_WIDTH  (90)
  112. #define C_PERIOD_WIDTH (90)
  113. #define C_RAND_WIDTH (90)
  114.  
  115. #define SLIDER_MIN ((SHORT)-314)
  116. #define SLIDER_MAX ((SHORT)314)
  117. #define PHASE_FACTOR (100.0)
  118.  
  119. #define C_PHASE_HEIGHT (12)
  120. #define C_INNER_WINDOW (625)
  121. #define C_COLUMN_WIDTH (C_INNER_WINDOW / 4)
  122. #define C_PERIOD_ADJUST ((C_COLUMN_WIDTH - C_PERIOD_WIDTH) / 2)
  123. #define C_PHASE_ADJUST  ((C_COLUMN_WIDTH - C_PHASE_WIDTH) / 2)
  124. #define C_RAND_ADJUST   ((C_COLUMN_WIDTH - C_RAND_WIDTH) / 2)
  125.  
  126. static char 
  127.         *maxvoices_str[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9",
  128.             "10", "11", "12", "13", "14", "15", "16", "17", "18", 
  129.             "19", "20", NULL};
  130.  
  131. static struct Node scales_nodes[23] 
  132.     = {{&scales_nodes[1], NULL, 0, 0, NULL},
  133.        {&scales_nodes[2], &scales_nodes[0], 0, 0, SCALE_1_NAME}, 
  134.        {&scales_nodes[3], &scales_nodes[1], 0, 0, SCALE_2_NAME}, 
  135.        {&scales_nodes[4], &scales_nodes[2], 0, 0, SCALE_3_NAME}, 
  136.        {&scales_nodes[5], &scales_nodes[3], 0, 0, SCALE_4_NAME}, 
  137.        {&scales_nodes[6], &scales_nodes[4], 0, 0, SCALE_5_NAME}, 
  138.        {&scales_nodes[7], &scales_nodes[5], 0, 0, SCALE_6_NAME}, 
  139.        {&scales_nodes[8], &scales_nodes[6], 0, 0, SCALE_7_NAME}, 
  140.        {&scales_nodes[9], &scales_nodes[7], 0, 0, SCALE_8_NAME}, 
  141.        {&scales_nodes[10], &scales_nodes[8], 0, 0, SCALE_9_NAME}, 
  142.        {&scales_nodes[11], &scales_nodes[9], 0, 0, SCALE_10_NAME}, 
  143.        {&scales_nodes[12], &scales_nodes[10], 0, 0, SCALE_11_NAME}, 
  144.        {&scales_nodes[13], &scales_nodes[11], 0, 0, SCALE_12_NAME}, 
  145.        {&scales_nodes[14], &scales_nodes[12], 0, 0, SCALE_13_NAME}, 
  146.        {&scales_nodes[15], &scales_nodes[13], 0, 0, SCALE_14_NAME}, 
  147.        {&scales_nodes[16], &scales_nodes[14], 0, 0, SCALE_15_NAME}, 
  148.        {&scales_nodes[17], &scales_nodes[15], 0, 0, SCALE_16_NAME}, 
  149.        {&scales_nodes[18], &scales_nodes[16], 0, 0, SCALE_17_NAME}, 
  150.        {&scales_nodes[19], &scales_nodes[17], 0, 0, SCALE_18_NAME}, 
  151.        {&scales_nodes[20], &scales_nodes[18], 0, 0, SCALE_19_NAME}, 
  152.        {&scales_nodes[21], &scales_nodes[19], 0, 0, SCALE_20_NAME}, 
  153.        {&scales_nodes[22], &scales_nodes[20], 0, 0, SCALE_21_NAME}, 
  154.        {NULL,              &scales_nodes[21], 0, 0, NULL}
  155. };
  156.  
  157. static char pitch_str[] = "PITCH",
  158.             pace_str[] = "PACE",
  159.             dyn_str[] = "DYNAMIC",
  160.             texture_str[] = "TEXTURE",
  161.             note_len_str[] = "DURATION";
  162. static struct IntuiText 
  163.     pitch_txt = {2, 2, INVERSVID | JAM1, 105, 67, 
  164.                 &font_choice, pitch_str, NULL},
  165.     pace_txt = {2, 2, INVERSVID | JAM1, 245, 67, 
  166.                 &font_choice, pace_str, &pitch_txt},
  167.     dyn_txt = {2, 2, INVERSVID | JAM1, 370, 67, 
  168.                 &font_choice,dyn_str, &pace_txt},
  169.     texture_txt = {2, 2, INVERSVID | JAM1, 500, 67, 
  170.                 &font_choice,texture_str, &dyn_txt},
  171.     note_len_txt = {2, 2, INVERSVID | JAM1, C_MIN_X + 10, 
  172.                 C_TOP_LINE, &font_choice,note_len_str, &texture_txt};
  173.  
  174. static struct Window *form_wind = NULL;
  175. static struct Gadget    *glist = NULL, 
  176.                         *form_gads[GAD_LAST];
  177. ULONG forms_mask = 0;
  178.  
  179. static struct Gadget 
  180.     *create_form_gadgets(void *vi, 
  181.     UWORD topborder, struct Gadget *form_gads[]);
  182. static SHORT phase_dbl_to_short(const double phase_dbl);
  183.  
  184. static VOID form_event( struct Gadget *gad, UWORD code,
  185.                         FORM_TYPE *form, struct timeval *duration, 
  186.                         int *tempo, 
  187.                         NOTE_EVENT_TYPE *events, NOTE_LEN_TYPE *note_len,
  188.                         int *max_voices, int *scale, int *range, 
  189.                         int *half_range, int *delay_ticks);
  190.  
  191. static VOID form_event( struct Gadget *gad, UWORD code, FORM_TYPE *form, 
  192.                         struct timeval *duration, int *tempo, 
  193.                         NOTE_EVENT_TYPE *events, NOTE_LEN_TYPE *note_len,
  194.                         int *max_voices, int *scale, int *range,
  195.                         int *half_range, int *delay_ticks)
  196. {
  197.     switch (gad->GadgetID)
  198.     {
  199.         case GAD_PITCH_MEAN_PER:
  200.             form->frm_s_pitch.prm_d_mean_cycle = (double)
  201.                 ((struct StringInfo *)(gad->SpecialInfo))->LongInt;
  202.             break;
  203.         case GAD_PITCH_MEAN_PHA:
  204.             form->frm_s_pitch.prm_d_mean_phase 
  205.               = ((double)(SHORT)code) / PHASE_FACTOR;
  206.             break;
  207.         case GAD_PITCH_RANG_PER:
  208.             form->frm_s_pitch.prm_d_range_cycle =
  209.                 (double)((struct StringInfo *)(gad->SpecialInfo))->LongInt;
  210.             break;
  211.         case GAD_PITCH_RANG_PHA:
  212.             form->frm_s_pitch.prm_d_range_phase 
  213.                 = ((double)(SHORT)code) / PHASE_FACTOR;
  214.             break;
  215.         case GAD_PITCH_RANDOMIZE:
  216.             randomize_parameter(&form->frm_s_pitch);
  217.             set_form_gadgets(form, duration, tempo, events, 
  218.                 note_len, *max_voices);
  219.             break;
  220.         case GAD_PACE_MEAN_PER:
  221.             form->frm_s_rhythm.prm_d_mean_cycle =
  222.                 (double)((struct StringInfo *)(gad->SpecialInfo))->LongInt;
  223.             break;
  224.         case GAD_PACE_MEAN_PHA:
  225.             form->frm_s_rhythm.prm_d_mean_phase 
  226.               = ((double)(SHORT)code) / PHASE_FACTOR;
  227.             break;
  228.         case GAD_PACE_RANG_PER:
  229.             form->frm_s_rhythm.prm_d_range_cycle =
  230.                 (double)((struct StringInfo *)(gad->SpecialInfo))->LongInt;
  231.             break;
  232.         case GAD_PACE_RANG_PHA:
  233.             form->frm_s_rhythm.prm_d_range_phase 
  234.               = ((double)(SHORT)code) / PHASE_FACTOR;
  235.             break;
  236.         case GAD_PACE_RANDOMIZE:
  237.             randomize_parameter(&form->frm_s_rhythm);
  238.             set_form_gadgets(form, duration, tempo, events, 
  239.                 note_len, *max_voices);
  240.             break;
  241.         case GAD_DYN_MEAN_PER:
  242.             form->frm_s_dynamic.prm_d_mean_cycle =
  243.                 (double)((struct StringInfo *)(gad->SpecialInfo))->LongInt;
  244.             break;
  245.         case GAD_DYN_MEAN_PHA:
  246.             form->frm_s_dynamic.prm_d_mean_phase 
  247.                 = ((double)(SHORT)code) / PHASE_FACTOR;
  248.             break;
  249.         case GAD_DYN_RANG_PER:
  250.             form->frm_s_dynamic.prm_d_range_cycle =
  251.                 (double)((struct StringInfo *)(gad->SpecialInfo))->LongInt;
  252.             break;
  253.         case GAD_DYN_RANG_PHA:
  254.             form->frm_s_dynamic.prm_d_range_phase 
  255.                 = ((double)(SHORT)code) / PHASE_FACTOR;
  256.             break;
  257.         case GAD_DYN_RANDOMIZE:
  258.             randomize_parameter(&form->frm_s_dynamic);
  259.             set_form_gadgets(form, duration, tempo, events, 
  260.                 note_len, *max_voices);
  261.             break;
  262.         case GAD_TEXTURE_RANG_PER:
  263.             form->frm_s_texture.prm_d_range_cycle =
  264.                 (double)((struct StringInfo *)(gad->SpecialInfo))->LongInt;
  265.             break;
  266.         case GAD_TEXTURE_RANG_PHA:
  267.             form->frm_s_texture.prm_d_range_phase 
  268.               = ((double)(SHORT)code) / PHASE_FACTOR;
  269.             break;
  270.         case GAD_TEXTURE_RANDOMIZE:
  271.             randomize_parameter(&form->frm_s_texture);
  272.             set_form_gadgets(form, duration, tempo, events, 
  273.                 note_len, *max_voices);
  274.             break;
  275.         case GAD_DURATION:
  276.             duration->tv_micro = 0L;
  277.             duration->tv_secs = 
  278.                 abs(((struct StringInfo *)(gad->SpecialInfo))->LongInt);
  279.             break;
  280.         case GAD_PULSE:
  281.             *tempo =
  282.                 abs(((struct StringInfo *)(gad->SpecialInfo))->LongInt);
  283.             if (*tempo > 0)
  284.             {
  285.                 *delay_ticks = 50 / *tempo;
  286.             }
  287.             else
  288.             {
  289.                 *delay_ticks = 0;
  290.             }
  291.             break;
  292.         case GAD_MAXVOICES:
  293.             *max_voices = code + 1;
  294.             break;
  295.         case GAD_NOTE_LEN_MIN:
  296.             note_len->len_i_min = (int)floor(strtod
  297.                 (((struct StringInfo *)(gad->SpecialInfo))->Buffer, 
  298.                 (char **)NULL)
  299.                 * 1000.0);
  300.             note_len->len_i_dif 
  301.                 = note_len->len_i_max - note_len->len_i_min;
  302.             break;
  303.         case GAD_NOTE_LEN_MAX:
  304.             note_len->len_i_max = (int)floor(strtod
  305.                 (((struct StringInfo *)(gad->SpecialInfo))->Buffer, 
  306.                 (char **)NULL)
  307.                 * 1000.0);
  308.             note_len->len_i_dif 
  309.                 = note_len->len_i_max - note_len->len_i_min;
  310.             break;
  311.         case GAD_SCALES:
  312.             *range = install_scale(code + 1, scale);
  313.             *half_range = *range / 2;
  314.             break;
  315.         case GAD_TRANSPOSE:
  316.             transpose_scale(
  317.               ((struct StringInfo *)(gad->SpecialInfo))->LongInt,
  318.               scale, *range);
  319.             break;
  320.     }
  321.     return;
  322. }
  323.  
  324. static struct Gadget *create_form_gadgets( 
  325.     void *vi, UWORD topborder, struct Gadget *form_gads[])
  326. {
  327.     auto struct TagItem /* ti_Tag, ti_Data */
  328.          phase_tag_items[] =   {{GTSL_Level,    0L},
  329.                                 {GTSL_Min,      SLIDER_MIN}, 
  330.                                 {GTSL_Max,      SLIDER_MAX},
  331.                                 {GTSL_LevelFormat, (ULONG)"%4ld"}, 
  332.                                 {GTSL_MaxLevelLen, 4}, 
  333.                                 {GTSL_LevelPlace, PLACETEXT_RIGHT}, 
  334.                                 {TAG_END,       0}},
  335.         period_tag_items[] = {  {GTIN_Number,   0L}, {TAG_END, 0L}},
  336.         rand_tag_items[] =   {  {TAG_END, 0L}},
  337.         note_len_items[] =   {  {GTST_String, NULL},
  338.                                 {GTST_MaxChars, 10}, 
  339.                                 {TAG_END, 0L}};
  340.     auto struct NewGadget ng;
  341.     auto struct Gadget *gad;
  342.  
  343.     gad = CreateContext(&glist);
  344.  
  345.     /*
  346.     ** Set up Pitch parameters
  347.     */
  348.     /*
  349.     ** First set up Pitch Mean Period 
  350.     */
  351.     ng.ng_LeftEdge = C_PITCH_X + C_PERIOD_ADJUST;
  352.     ng.ng_TopEdge = C_MEAN_PERIOD_Y;
  353.     ng.ng_Width = C_PERIOD_WIDTH;
  354.     ng.ng_Height = 12;
  355.     ng.ng_GadgetText = "MEAN Per";
  356.     ng.ng_TextAttr = &font_choice;
  357.     ng.ng_VisualInfo = vi;
  358.     ng.ng_GadgetID = GAD_PITCH_MEAN_PER;
  359.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_LEFT;
  360.     form_gads[GAD_PITCH_MEAN_PER] 
  361.         = gad = CreateGadgetA(INTEGER_KIND, gad, &ng, period_tag_items);
  362.     /*
  363.     ** Set up Pitch Mean Phase
  364.     */
  365.     ng.ng_LeftEdge  = C_PITCH_X + C_PHASE_ADJUST;
  366.     ng.ng_TopEdge   = C_MEAN_PHASE_Y;
  367.     ng.ng_Width     = C_PHASE_WIDTH;
  368.     ng.ng_Height    = C_PHASE_HEIGHT;
  369.     ng.ng_GadgetText = "Phase";
  370.     ng.ng_GadgetID  = GAD_PITCH_MEAN_PHA;
  371.     form_gads[GAD_PITCH_MEAN_PHA] = gad = 
  372.         CreateGadgetA(SLIDER_KIND, gad, &ng, phase_tag_items);
  373.     /*
  374.     ** Set up Pitch Range Period
  375.     */
  376.     ng.ng_LeftEdge = C_PITCH_X + C_PERIOD_ADJUST;
  377.     ng.ng_TopEdge = C_RANG_PERIOD_Y;
  378.     ng.ng_Width = C_PERIOD_WIDTH;
  379.     ng.ng_Height = 12;
  380.     ng.ng_GadgetText = "RANGE Per";
  381.     ng.ng_GadgetID = GAD_PITCH_RANG_PER;
  382.     form_gads[GAD_PITCH_RANG_PER] 
  383.         = gad = CreateGadgetA(INTEGER_KIND, gad, &ng, period_tag_items);
  384.     /*
  385.     ** Set up Pitch Range Phase
  386.     */
  387.     ng.ng_LeftEdge = C_PITCH_X + C_PHASE_ADJUST;
  388.     ng.ng_TopEdge = C_RANG_PHASE_Y;
  389.     ng.ng_Width = C_PHASE_WIDTH;
  390.     ng.ng_Height = C_PHASE_HEIGHT;
  391.     ng.ng_GadgetText = "Phase";
  392.     ng.ng_GadgetID = GAD_PITCH_RANG_PHA;
  393.     form_gads[GAD_PITCH_RANG_PHA] = gad = 
  394.         CreateGadgetA(SLIDER_KIND, gad, &ng, phase_tag_items);
  395.     /*
  396.     ** Set up Pitch Randomize
  397.     */
  398.     ng.ng_LeftEdge = C_PITCH_X + C_RAND_ADJUST;
  399.     ng.ng_TopEdge = C_RAND_Y;
  400.     ng.ng_Width = C_RAND_WIDTH;
  401.     ng.ng_Height = 12;
  402.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_IN;
  403.     ng.ng_GadgetText = "Randomize";
  404.     ng.ng_GadgetID = GAD_PITCH_RANDOMIZE;
  405.     form_gads[GAD_PITCH_RANDOMIZE] 
  406.         = gad = CreateGadgetA(BUTTON_KIND, gad, &ng, rand_tag_items);
  407.     /*
  408.     ** Set up Pace
  409.     */
  410.     /*
  411.     ** Set up Pace Mean Period
  412.     */
  413.     ng.ng_LeftEdge = C_PACE_X + C_PERIOD_ADJUST;
  414.     ng.ng_TopEdge = C_MEAN_PERIOD_Y;
  415.     ng.ng_Width = C_PERIOD_WIDTH;
  416.     ng.ng_Height = 12;
  417.     ng.ng_Flags = 0;
  418.     ng.ng_GadgetText = NULL;
  419.     ng.ng_GadgetID = GAD_PACE_MEAN_PER;
  420.     form_gads[GAD_PACE_MEAN_PER] = gad 
  421.         = CreateGadgetA(INTEGER_KIND, gad, &ng, period_tag_items);
  422.     /*
  423.     ** Set up Pace Mean Phase
  424.     */
  425.     ng.ng_LeftEdge = C_PACE_X + C_PHASE_ADJUST;
  426.     ng.ng_TopEdge = C_MEAN_PHASE_Y;
  427.     ng.ng_Width = C_PHASE_WIDTH;
  428.     ng.ng_Height = C_PHASE_HEIGHT;
  429.     ng.ng_GadgetText = NULL;
  430.     ng.ng_GadgetID = GAD_PACE_MEAN_PHA;
  431.     form_gads[GAD_PACE_MEAN_PHA] = gad = 
  432.         CreateGadgetA(SLIDER_KIND, gad, &ng, phase_tag_items);
  433.     /*
  434.     ** Set up Pace Range Period
  435.     */
  436.     ng.ng_LeftEdge = C_PACE_X + C_PERIOD_ADJUST;
  437.     ng.ng_TopEdge = C_RANG_PERIOD_Y;
  438.     ng.ng_Width = C_PERIOD_WIDTH;
  439.     ng.ng_Height = 12;
  440.     ng.ng_GadgetText = NULL;
  441.     ng.ng_GadgetID = GAD_PACE_RANG_PER;
  442.     form_gads[GAD_PACE_RANG_PER] = gad 
  443.         = CreateGadgetA(INTEGER_KIND, gad, &ng, period_tag_items);
  444.     /*
  445.     ** Set up Pace Range Phase
  446.     */
  447.     ng.ng_LeftEdge = C_PACE_X + C_PHASE_ADJUST;
  448.     ng.ng_TopEdge = C_RANG_PHASE_Y;
  449.     ng.ng_Width = C_PHASE_WIDTH;
  450.     ng.ng_Height = C_PHASE_HEIGHT;
  451.     ng.ng_GadgetText = NULL;
  452.     ng.ng_GadgetID = GAD_PACE_RANG_PHA;
  453.     form_gads[GAD_PACE_RANG_PHA] = gad = 
  454.         CreateGadgetA(SLIDER_KIND, gad, &ng, phase_tag_items);
  455.     /*
  456.     ** Set up Pace Randomize
  457.     */
  458.     ng.ng_LeftEdge = C_PACE_X + C_RAND_ADJUST;
  459.     ng.ng_TopEdge = C_RAND_Y;
  460.     ng.ng_Width = C_RAND_WIDTH;
  461.     ng.ng_Height = 12;
  462.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_IN;
  463.     ng.ng_GadgetText = "Randomize";
  464.     ng.ng_GadgetID = GAD_PACE_RANDOMIZE;
  465.     form_gads[GAD_PACE_RANDOMIZE] = gad 
  466.         = CreateGadgetA(BUTTON_KIND, gad, &ng, rand_tag_items);
  467.     /*
  468.     ** Set up Dynamics
  469.     */
  470.     /*
  471.     ** Set up Dynamic Mean Period
  472.     */
  473.     ng.ng_LeftEdge = C_DYN_X + C_PERIOD_ADJUST;
  474.     ng.ng_TopEdge = C_MEAN_PERIOD_Y;
  475.     ng.ng_Width = C_PERIOD_WIDTH;
  476.     ng.ng_Height = 12;
  477.     ng.ng_GadgetText = NULL;
  478.     ng.ng_Flags = 0L;
  479.     ng.ng_GadgetID = GAD_DYN_MEAN_PER;
  480.     form_gads[GAD_DYN_MEAN_PER] = gad 
  481.         = CreateGadgetA(INTEGER_KIND, gad, &ng, period_tag_items);
  482.     /*
  483.     ** Set up Dynamic Mean Phase
  484.     */
  485.     ng.ng_LeftEdge = C_DYN_X + C_PHASE_ADJUST;
  486.     ng.ng_TopEdge = C_MEAN_PHASE_Y;
  487.     ng.ng_Width = C_PHASE_WIDTH;
  488.     ng.ng_Height = C_PHASE_HEIGHT;
  489.     ng.ng_GadgetText = NULL;
  490.     ng.ng_GadgetID = GAD_DYN_MEAN_PHA;
  491.     form_gads[GAD_DYN_MEAN_PHA] = gad = 
  492.         CreateGadgetA(SLIDER_KIND, gad, &ng, phase_tag_items);
  493.     /*
  494.     ** Set up Dynamic Range Period
  495.     */
  496.     ng.ng_LeftEdge = C_DYN_X + C_PERIOD_ADJUST;
  497.     ng.ng_TopEdge = C_RANG_PERIOD_Y;
  498.     ng.ng_Width = C_PERIOD_WIDTH;
  499.     ng.ng_Height = 12;
  500.     ng.ng_GadgetText = NULL;
  501.     ng.ng_GadgetID = GAD_DYN_RANG_PER;
  502.     form_gads[GAD_DYN_RANG_PER] = gad 
  503.         = CreateGadgetA(INTEGER_KIND, gad, &ng, period_tag_items);
  504.     /*
  505.     ** Set up Dynamic Range Phase
  506.     */
  507.     ng.ng_LeftEdge = C_DYN_X + C_PHASE_ADJUST;
  508.     ng.ng_TopEdge = C_RANG_PHASE_Y;
  509.     ng.ng_Width = C_PHASE_WIDTH;
  510.     ng.ng_Height = C_PHASE_HEIGHT;
  511.     ng.ng_GadgetText = NULL;
  512.     ng.ng_GadgetID = GAD_DYN_RANG_PHA;
  513.     form_gads[GAD_DYN_RANG_PHA] = gad = 
  514.         CreateGadgetA(SLIDER_KIND, gad, &ng, phase_tag_items);
  515.     /*
  516.     ** Set up Dynamic Randomize
  517.     */
  518.     ng.ng_LeftEdge = C_DYN_X + C_RAND_ADJUST;
  519.     ng.ng_TopEdge = C_RAND_Y;
  520.     ng.ng_Width = C_RAND_WIDTH;
  521.     ng.ng_Height = 12;
  522.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_IN;
  523.     ng.ng_GadgetText = "Randomize";
  524.     ng.ng_GadgetID = GAD_DYN_RANDOMIZE;
  525.     form_gads[GAD_DYN_RANDOMIZE] = gad 
  526.         = CreateGadgetA(BUTTON_KIND, gad, &ng, rand_tag_items);
  527.     /*
  528.     ** Set up Texture
  529.     */
  530.     /*
  531.     ** Set up Texture Range Period
  532.     */
  533.     ng.ng_LeftEdge = C_TEXTURE_X + C_PERIOD_ADJUST;
  534.     ng.ng_TopEdge = C_RANG_PERIOD_Y;
  535.     ng.ng_Width = C_PERIOD_WIDTH;
  536.     ng.ng_Height = 12;
  537.     ng.ng_GadgetText = NULL;
  538.     ng.ng_Flags = NULL;
  539.     ng.ng_GadgetID = GAD_TEXTURE_RANG_PER;
  540.     form_gads[GAD_TEXTURE_RANG_PER] 
  541.         = gad = CreateGadgetA(INTEGER_KIND, gad, &ng, period_tag_items);
  542.     /*
  543.     ** Set up Texture Range Phase
  544.     */
  545.     ng.ng_LeftEdge = C_TEXTURE_X + C_PHASE_ADJUST;
  546.     ng.ng_TopEdge = C_RANG_PHASE_Y;
  547.     ng.ng_Width = C_PHASE_WIDTH;
  548.     ng.ng_Height = C_PHASE_HEIGHT;
  549.     ng.ng_GadgetText = NULL;
  550.     ng.ng_GadgetID = GAD_TEXTURE_RANG_PHA;
  551.     form_gads[GAD_TEXTURE_RANG_PHA] = gad = 
  552.         CreateGadgetA(SLIDER_KIND, gad, &ng, phase_tag_items);
  553.     /*
  554.     ** Set up Texture Randomize
  555.     */
  556.     ng.ng_LeftEdge = C_TEXTURE_X + C_RAND_ADJUST;
  557.     ng.ng_TopEdge = C_RAND_Y;
  558.     ng.ng_Width = C_RAND_WIDTH;
  559.     ng.ng_Height = 12;
  560.     ng.ng_GadgetText = "Randomize";
  561.     ng.ng_GadgetID = GAD_TEXTURE_RANDOMIZE;
  562.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_IN;
  563.     form_gads[GAD_TEXTURE_RANDOMIZE] 
  564.         = gad = CreateGadgetA(BUTTON_KIND, gad, &ng, rand_tag_items);
  565.     /*
  566.     ** Set up Duration
  567.     */
  568.     ng.ng_LeftEdge = C_DUR_X;
  569.     ng.ng_TopEdge = C_TOP_LINE;
  570.     ng.ng_Width = 80;
  571.     ng.ng_Height = 12;
  572.     ng.ng_GadgetText = "Duration";
  573.     ng.ng_GadgetID = GAD_DURATION;
  574.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_ABOVE;
  575.     form_gads[GAD_DURATION] = gad = CreateGadget(INTEGER_KIND, gad, &ng,
  576.         TAG_END);
  577.     /*
  578.     ** Set up Max Voices
  579.     */
  580.     ng.ng_LeftEdge = C_MAXVOICES_X;
  581.     ng.ng_TopEdge = C_TOP_LINE;
  582.     ng.ng_Width = 50;
  583.     ng.ng_Height = 12;
  584.     ng.ng_GadgetText = "MaxVoices";
  585.     ng.ng_GadgetID = GAD_MAXVOICES;
  586.     form_gads[GAD_MAXVOICES] 
  587.         = gad
  588.         = CreateGadget(CYCLE_KIND, gad, &ng, GTCY_Labels, maxvoices_str,
  589.         TAG_END); 
  590.     /*
  591.     ** Set up Scales list
  592.     */
  593.     ng.ng_LeftEdge = C_SCALES_X;
  594.     ng.ng_TopEdge = C_TOP_LINE - 10;
  595.     ng.ng_Width = 180;
  596.     ng.ng_Height = 48;
  597.     ng.ng_GadgetText = "Scale";
  598.     ng.ng_GadgetID = GAD_SCALES;
  599.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_LEFT;
  600.     form_gads[GAD_SCALES] = gad = CreateGadget(LISTVIEW_KIND, gad, &ng, 
  601.         GTLV_Labels, scales_nodes, GTLV_ShowSelected, NULL, TAG_END); 
  602.     /*
  603.     ** Set up Pulse
  604.     */
  605.     ng.ng_LeftEdge = C_PULSE_X;
  606.     ng.ng_TopEdge = C_2ND_LINE;
  607.     ng.ng_Width = 40;
  608.     ng.ng_Height = 12;
  609.     ng.ng_GadgetText = "Pulse";
  610.     ng.ng_GadgetID = GAD_PULSE;
  611.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_ABOVE;
  612.     form_gads[GAD_PULSE] = gad = CreateGadget(INTEGER_KIND, gad, &ng,
  613.         TAG_END);
  614.     /*
  615.     ** Set up minimum note length
  616.     */
  617.     ng.ng_LeftEdge = C_MIN_X;
  618.     ng.ng_TopEdge = C_2ND_LINE - 12;
  619.     ng.ng_Width = 80;
  620.     ng.ng_Height = 12;
  621.     ng.ng_GadgetText = "Min";
  622.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_LEFT;
  623.     ng.ng_GadgetID = GAD_NOTE_LEN_MIN;
  624.     form_gads[GAD_NOTE_LEN_MIN] = gad 
  625.         = CreateGadgetA(STRING_KIND, gad, &ng, note_len_items); 
  626.     /*
  627.     ** Set up maximum note length
  628.     */
  629.     ng.ng_LeftEdge = C_MAX_X;
  630.     ng.ng_TopEdge = C_2ND_LINE;
  631.     ng.ng_Width = 80;
  632.     ng.ng_Height = 12;
  633.     ng.ng_GadgetText = "Max";
  634.     ng.ng_GadgetID = GAD_NOTE_LEN_MAX;
  635.     form_gads[GAD_NOTE_LEN_MAX] = gad 
  636.         = CreateGadgetA(STRING_KIND, gad, &ng, note_len_items); 
  637.     /*
  638.     ** Set up Transposition
  639.     */
  640.     ng.ng_LeftEdge = C_TRANSPOSE_X;
  641.     ng.ng_TopEdge = C_2ND_LINE;
  642.     ng.ng_Width = 60;
  643.     ng.ng_Height = 12;
  644.     ng.ng_GadgetText = "Transpose";
  645.     ng.ng_GadgetID = GAD_TRANSPOSE;
  646.     ng.ng_Flags = NG_HIGHLABEL | PLACETEXT_ABOVE;
  647.     form_gads[GAD_TRANSPOSE] = gad = CreateGadget(INTEGER_KIND, gad, &ng,
  648.         GTST_String, "0", GTST_MaxChars, 3,
  649.         TAG_END); 
  650.  
  651.     return gad;
  652. }
  653.  
  654. int process_form_events(FORM_TYPE *form, struct timeval *duration, 
  655.                         int *tempo, 
  656.                         NOTE_EVENT_TYPE *events, NOTE_LEN_TYPE *note_len,
  657.                         int *max_voices, int *scale, int *range,
  658.                         int *half_range, int *delay_ticks)
  659. {
  660.     auto int result = 0;
  661.     auto int Closing = FALSE;
  662.     auto ULONG imsgClass;
  663.     auto UWORD imsgCode;
  664.     auto struct Gadget *gad;
  665.     auto struct IntuiMessage *imsg;
  666.  
  667.     while (imsg = GT_GetIMsg(form_wind->UserPort))
  668.     {
  669.         gad = (struct Gadget *)imsg->IAddress;
  670.         imsgClass = imsg->Class;
  671.         imsgCode = imsg->Code;
  672.         GT_ReplyIMsg(imsg);
  673.         switch(imsgClass)
  674.         {
  675.             case IDCMP_CLOSEWINDOW:
  676.                 Closing = TRUE;
  677.                 break;
  678.             case IDCMP_GADGETDOWN:
  679.             case IDCMP_MOUSEMOVE:
  680.             case IDCMP_GADGETUP:
  681.                 form_event(gad, imsgCode, form, duration, tempo, 
  682.                         events, note_len, max_voices, scale, range,
  683.                         half_range, delay_ticks);
  684.                 result = 1;
  685.                 break;
  686.             case IDCMP_REFRESHWINDOW:
  687.                 GT_BeginRefresh(form_wind);
  688.                 SetAPen(rast_port, 2);
  689.                 PrintIText(form_wind->RPort, ¬e_len_txt, 1, 1);
  690.                 GT_EndRefresh(form_wind, TRUE);
  691.                 break;
  692.         }
  693.     }
  694.     if (Closing)
  695.     {
  696.         close_forms();
  697.     }
  698.     return result;
  699. }
  700.  
  701. VOID open_forms_window(VOID)
  702. {
  703.     auto UWORD   topborder;
  704.     
  705.     if (form_wind != NULL)
  706.     {
  707.         return;
  708.     }
  709.     topborder = main_screen->WBorTop
  710.         + (main_screen->Font->ta_YSize + 1);
  711.     if (NULL == create_form_gadgets(vi, topborder, 
  712.                   form_gads))
  713.     {
  714.         ;
  715.     }
  716.     else
  717.     {
  718.         if (NULL == (form_wind = OpenWindowTags(NULL,
  719.                   WA_Top, 59,
  720.                   WA_Title, "FORM PARAMETERS",
  721.                   WA_Gadgets, glist, WA_AutoAdjust, TRUE,
  722.                   WA_Width, 640, WA_MinWidth, 640,
  723.                   WA_InnerHeight, 130, WA_MinHeight, 140,
  724.                   WA_DragBar, TRUE, WA_DepthGadget, TRUE,
  725.                   WA_Activate, TRUE,
  726. #if 0
  727.                   WA_CloseGadget, TRUE,
  728. #endif
  729.                   WA_SimpleRefresh, TRUE,
  730.                   WA_IDCMP, IDCMP_REFRESHWINDOW /* | IDCMP_CLOSEWINDOW */ 
  731.                   | SLIDERIDCMP | LISTVIEWIDCMP 
  732.                   | STRINGIDCMP | BUTTONIDCMP | CYCLEIDCMP,
  733.                   WA_CustomScreen, main_screen, TAG_DONE, 0UL)))
  734.         {
  735.             ;
  736.         }
  737.         else
  738.         {
  739.             RefreshGList(glist, form_wind, NULL, -1);
  740.             GT_RefreshWindow(form_wind, NULL);
  741.             SetAPen(rast_port, 2);
  742.             PrintIText(form_wind->RPort, ¬e_len_txt, 1, 1);
  743.             forms_mask = 1 << form_wind->UserPort->mp_SigBit;
  744.         }
  745.     }
  746.     return;
  747. }
  748.  
  749. void close_forms(void)
  750. {
  751.     RemoveGList(form_wind, glist, -1);
  752.     CloseWindowSafely(form_wind);
  753.     form_wind = NULL;
  754.     FreeGadgets(glist);
  755.     glist = NULL;
  756.     return;
  757. }
  758.  
  759. void set_form_gadgets(FORM_TYPE *form, struct timeval *duration, 
  760.                         int *tempo, 
  761.                         NOTE_EVENT_TYPE *events, NOTE_LEN_TYPE *note_len,
  762.                         int max_voices)
  763. {
  764.     auto char temp_str[24];
  765.     auto int gad_index;
  766.  
  767.     GT_SetGadgetAttrs(form_gads[GAD_PITCH_MEAN_PER], form_wind, 
  768.         NULL, GTIN_Number, (int)floor(form->frm_s_pitch.prm_d_mean_cycle), 
  769.         TAG_END, 0L);
  770.     GT_SetGadgetAttrs(form_gads[GAD_PITCH_MEAN_PHA], form_wind, 
  771.         NULL, GTSL_Level, 
  772.         phase_dbl_to_short(form->frm_s_pitch.prm_d_mean_phase),
  773.         TAG_END, 0L);
  774.     GT_SetGadgetAttrs(form_gads[GAD_PITCH_RANG_PER], form_wind, 
  775.         NULL, GTIN_Number, (int)floor(form->frm_s_pitch.prm_d_range_cycle),
  776.         TAG_END, 0L);
  777.     GT_SetGadgetAttrs(form_gads[GAD_PITCH_RANG_PHA], form_wind, 
  778.         NULL, GTSL_Level, 
  779.         phase_dbl_to_short(form->frm_s_pitch.prm_d_range_phase),
  780.         TAG_END, 0L);
  781.     GT_SetGadgetAttrs(form_gads[GAD_PACE_MEAN_PER], form_wind, 
  782.         NULL, GTIN_Number, (int)floor(form->frm_s_rhythm.prm_d_mean_cycle),
  783.         TAG_END, 0L);
  784.     GT_SetGadgetAttrs(form_gads[GAD_PACE_MEAN_PHA], form_wind, 
  785.         NULL, GTSL_Level, 
  786.         phase_dbl_to_short(form->frm_s_rhythm.prm_d_mean_phase),
  787.         TAG_END, 0L);
  788.     GT_SetGadgetAttrs(form_gads[GAD_PACE_RANG_PER], form_wind,
  789.         NULL, GTIN_Number, (int)floor(form->frm_s_rhythm.prm_d_range_cycle),
  790.         TAG_END, 0L);
  791.     GT_SetGadgetAttrs(form_gads[GAD_PACE_RANG_PHA], form_wind, 
  792.         NULL, GTSL_Level, 
  793.         phase_dbl_to_short(form->frm_s_rhythm.prm_d_range_phase),
  794.         TAG_END, 0L);
  795.     GT_SetGadgetAttrs(form_gads[GAD_DYN_MEAN_PER], form_wind, 
  796.         NULL, GTIN_Number, (int)floor(form->frm_s_dynamic.prm_d_mean_cycle), 
  797.         TAG_END, 0L);
  798.     GT_SetGadgetAttrs(form_gads[GAD_DYN_MEAN_PHA], form_wind, 
  799.         NULL, GTSL_Level, 
  800.         phase_dbl_to_short(form->frm_s_dynamic.prm_d_mean_phase),
  801.         TAG_END, 0L);
  802.     GT_SetGadgetAttrs(form_gads[GAD_DYN_RANG_PER], form_wind, 
  803.         NULL, GTIN_Number, (int)floor(form->frm_s_dynamic.prm_d_range_cycle), 
  804.         TAG_END, 0L);
  805.     GT_SetGadgetAttrs(form_gads[GAD_DYN_RANG_PHA], form_wind, 
  806.         NULL, GTSL_Level,
  807.         phase_dbl_to_short(form->frm_s_dynamic.prm_d_range_phase),
  808.         TAG_END, 0L);
  809.     GT_SetGadgetAttrs(form_gads[GAD_TEXTURE_RANG_PER], form_wind, 
  810.         NULL, GTIN_Number, (int)floor(form->frm_s_texture.prm_d_range_cycle), 
  811.         TAG_END, 0L);
  812.     GT_SetGadgetAttrs(form_gads[GAD_TEXTURE_RANG_PHA], form_wind, 
  813.         NULL, GTSL_Level, 
  814.         phase_dbl_to_short(form->frm_s_texture.prm_d_range_phase),
  815.         TAG_END, 0L);
  816.     GT_SetGadgetAttrs(form_gads[GAD_PULSE], form_wind, 
  817.         NULL, GTIN_Number, *tempo, TAG_END, 0L);
  818.     sprintf(temp_str, "%5.2f", note_len->len_i_min / 1000.0);
  819.     GT_SetGadgetAttrs(form_gads[GAD_NOTE_LEN_MIN], form_wind, 
  820.         NULL, GTST_String, temp_str, TAG_END, 0L);
  821.     sprintf(temp_str, "%5.2f", note_len->len_i_max / 1000.0);
  822.     GT_SetGadgetAttrs(form_gads[GAD_NOTE_LEN_MAX], form_wind, 
  823.         NULL, GTST_String, temp_str, TAG_END, 0L);
  824.     GT_SetGadgetAttrs(form_gads[GAD_DURATION], form_wind,
  825.         NULL, GTIN_Number, duration->tv_secs, TAG_END, 0L);
  826.     GT_SetGadgetAttrs(form_gads[GAD_MAXVOICES], form_wind,
  827.         NULL, GTCY_Active, max_voices - 1, TAG_END, 0L);
  828.     return;
  829. }
  830.  
  831. static SHORT phase_dbl_to_short(const double phase_dbl)
  832. {
  833.     auto SHORT tmp_short;
  834.  
  835.     tmp_short = (SHORT)(floor(fabs(phase_dbl * PHASE_FACTOR) + 0.5));
  836.     if (phase_dbl < 0.0)
  837.     {
  838.         tmp_short = -tmp_short;
  839.     }
  840.     return tmp_short;
  841. }
  842.